using System.Security.Cryptography;
using System.Text.Json;
using System.IO;
using KeyAuthService.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using System.Windows;

namespace KeyAuthService.Services
{
    /// <summary>
    /// 密钥存储服务
    /// </summary>
    public class KeyStorageService
    {
        private readonly ILogger<KeyStorageService> _logger;
        private readonly string _storageFolder;
        private readonly string _keysFile;
        private readonly Dictionary<string, KeyInfo> _keyCache = new Dictionary<string, KeyInfo>();
        private bool _isInitialized = false;

        public KeyStorageService(ILogger<KeyStorageService> logger)
        {
            _logger = logger;
            
            // 设置存储目录和文件
            _storageFolder = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                "KeyAuthService");
            
            _keysFile = Path.Combine(_storageFolder, "keys.dat");
            
            // 确保目录存在
            if (!Directory.Exists(_storageFolder))
            {
                Directory.CreateDirectory(_storageFolder);
            }
        }

        /// <summary>
        /// 初始化存储服务
        /// </summary>
        public void Initialize()
        {
            if (_isInitialized) return;

            try
            {
                // 加载密钥数据
                LoadKeys();
                _isInitialized = true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "初始化密钥存储服务失败");
                throw;
            }
        }

        /// <summary>
        /// 加载密钥数据
        /// </summary>
        private void LoadKeys()
        {
            if (!File.Exists(_keysFile))
            {
                _logger.LogInformation("密钥文件不存在，将创建新文件");
                SaveKeys();
                return;
            }

            try
            {
                // 读取加密数据
                byte[] encryptedData = File.ReadAllBytes(_keysFile);
                
                // 解密数据
                byte[] decryptedData = ProtectedData.Unprotect(
                    encryptedData, 
                    null, 
                    DataProtectionScope.LocalMachine);
                
                // 反序列化
                string json = System.Text.Encoding.UTF8.GetString(decryptedData);
                var keys = JsonSerializer.Deserialize<List<KeyInfo>>(json);
                
                if (keys != null)
                {
                    _keyCache.Clear();
                    foreach (var key in keys)
                    {
                        _keyCache[key.KeyName] = key;
                    }
                    _logger.LogInformation($"成功加载 {_keyCache.Count} 个密钥");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "加载密钥数据失败");
                throw;
            }
        }

        /// <summary>
        /// 保存密钥数据
        /// </summary>
        private void SaveKeys()
        {
            try
            {
                // 序列化
                string json = JsonSerializer.Serialize(_keyCache.Values.ToList());
                byte[] data = System.Text.Encoding.UTF8.GetBytes(json);
                
                // 加密数据
                byte[] encryptedData = ProtectedData.Protect(
                    data, 
                    null, 
                    DataProtectionScope.LocalMachine);
                
                // 写入文件
                File.WriteAllBytes(_keysFile, encryptedData);
                _logger.LogInformation("密钥数据保存成功");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "保存密钥数据失败");
                throw;
            }
        }

        /// <summary>
        /// 添加密钥
        /// </summary>
        public bool AddKey(KeyInfo keyInfo)
        {
            if (!_isInitialized) Initialize();

            try
            {
                if (_keyCache.ContainsKey(keyInfo.KeyName))
                {
                    _logger.LogWarning($"密钥 {keyInfo.KeyName} 已存在");
                    return false;
                }

                _keyCache[keyInfo.KeyName] = keyInfo;
                SaveKeys();
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"添加密钥 {keyInfo.KeyName} 失败");
                return false;
            }
        }

        /// <summary>
        /// 获取密钥
        /// </summary>
        public KeyInfo? GetKey(string keyName)
        {
            if (!_isInitialized) Initialize();

            if (_keyCache.TryGetValue(keyName, out var keyInfo))
            {
                return keyInfo;
            }
            return null;
        }

        /// <summary>
        /// 根据客户端ID获取授权的密钥
        /// </summary>
        /// <param name="clientId">客户端ID</param>
        /// <returns>授权的密钥信息，如果未找到则返回null</returns>
        public KeyInfo? GetAuthorizedKey(string clientId)
        {
            if (string.IsNullOrEmpty(clientId))
                return null;

            try
            {
                // 从WebSocketServer获取连接的授权密钥名称
                var app = (App)Application.Current;
                var webSocketServer = app.ServiceProvider.GetService<WebSocketServer>();
                if (webSocketServer == null) return null;

                // 获取连接使用的密钥名称
                string? keyName = webSocketServer.GetConnectionAuthKey(clientId);
                if (string.IsNullOrEmpty(keyName))
                    return null;

                // 返回对应的密钥
                var keyInfo = GetKey(keyName);
                
                // 如果密钥的Address为空，尝试从连接信息中获取
                if (keyInfo != null && string.IsNullOrEmpty(keyInfo.Address))
                {
                    string? keyAddress = webSocketServer.GetConnectionKeyAddress(clientId);
                    if (!string.IsNullOrEmpty(keyAddress))
                    {
                        keyInfo.Address = keyAddress;
                    }
                }
                
                return keyInfo;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取客户端 {clientId} 的授权密钥失败");
                return null;
            }
        }

        /// <summary>
        /// 获取所有密钥
        /// </summary>
        public List<KeyInfo> GetAllKeys()
        {
            if (!_isInitialized) Initialize();

            try
            {
                return _keyCache.Values.ToList();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取所有密钥失败");
                return new List<KeyInfo>();
            }
        }

        /// <summary>
        /// 删除密钥
        /// </summary>
        public bool DeleteKey(string keyName)
        {
            if (!_isInitialized) Initialize();

            try
            {
                if (_keyCache.Remove(keyName))
                {
                    SaveKeys();
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"删除密钥 {keyName} 失败");
                return false;
            }
        }

        /// <summary>
        /// 更新密钥
        /// </summary>
        public bool UpdateKey(KeyInfo keyInfo)
        {
            if (!_isInitialized) Initialize();

            try
            {
                if (!_keyCache.ContainsKey(keyInfo.KeyName))
                {
                    _logger.LogWarning($"密钥 {keyInfo.KeyName} 不存在");
                    return false;
                }

                _keyCache[keyInfo.KeyName] = keyInfo;
                SaveKeys();
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新密钥 {keyInfo.KeyName} 失败");
                return false;
            }
        }
    }
} 